home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / C Internet Config / IC Component Source ƒ / IC Resource ƒ / Syslog Component ƒ / syslog component.c < prev    next >
Encoding:
Text File  |  1995-11-15  |  20.3 KB  |  489 lines  |  [TEXT/SPM ]

  1. utines so we don't need to include ANSI libs
  2. static short Strlen(char* s){
  3.     register char* cp=s;
  4.     register short sh=0;
  5.     
  6.     if (s==(char*)0)
  7.         return 0;
  8.     
  9.     while (*cp){
  10.         sh++;
  11.         cp++;
  12.     }
  13.     
  14.     return sh;
  15. }
  16.  
  17. static void Strncpy(char* s1,char* s2,short num){
  18.     
  19.     // copy the strings
  20.     BlockMoveData((Ptr)s2,(Ptr)s1,num);
  21.     
  22.     // terminate the new string
  23.     s1[num]=0;
  24. }
  25.  
  26. static void Strcpy(char* s1,char* s2){
  27.     // Call strncpy with the string's length
  28.     Strncpy(s1,s2,Strlen(s2));
  29. }
  30.  
  31. static void ConcatPString(StringPtr a,StringPtr b);
  32. static void ConcatPString(StringPtr a,StringPtr b){
  33.     register unsigned char* ap;
  34.     register unsigned char* bp;
  35.     register unsigned char c;
  36.     
  37.     ap=&(a[a[0]+1]);
  38.     bp=b;bp++;
  39.     c=b[0];
  40.     
  41.     while (c){
  42.         *ap=*bp;
  43.         ap++;
  44.         bp++;
  45.         c--;
  46.     }
  47.     
  48.     (a[0])+=b[0];
  49. }
  50.     
  51. pascal ComponentResult main(ComponentParameters* params,Handle storage){
  52.     ComponentResult res=((ComponentResult)noErr);
  53.     long lval;
  54.     ComponentFunctionUPP cfupp;
  55.     
  56. #if defined(powerc) || defined(__powerc)
  57.     __rsrcinit();
  58. #endif
  59.     
  60.     switch(params->what){
  61.         // Component Manager Routines
  62.         case kComponentOpenSelect:
  63.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentOpen);
  64.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  65.             DisposeComponentWithStorageProc(cfupp);
  66.             break;
  67.         case kComponentCloseSelect:
  68.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentClose);
  69.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  70.             DisposeComponentWithStorageProc(cfupp);
  71.             break;
  72.         case kComponentCanDoSelect:
  73.             cfupp=(ComponentFunctionUPP)NewComponentShortProc(ComponentCanDo);
  74.             res=CallComponentFunction(params,cfupp);
  75.             DisposeComponentShortProc(cfupp);
  76.             break;
  77.         case kComponentVersionSelect:
  78.             cfupp=(ComponentFunctionUPP)NewComponentVoidProc(ComponentVersion);
  79.             res=CallComponentFunction(params,cfupp);
  80.             DisposeComponentVoidProc(cfupp);
  81.             break;
  82.         case kComponentTargetSelect:
  83.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentTarget);
  84.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  85.             DisposeComponentWithStorageProc(cfupp);
  86.             break;
  87.         case kComponentRegisterSelect:
  88.             cfupp=(ComponentFunctionUPP)NewComponentHandleProc(ComponentRegister);
  89.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  90.             DisposeComponentHandleProc(cfupp);
  91.             res=(ComponentResult)lval;
  92.             break;
  93.         
  94.         // Component Specific Routines
  95.             
  96.         case kopenlogSelector:
  97.             cfupp=(ComponentFunctionUPP)NewComponentOpenlogProc(ComponentOpenlog);
  98.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  99.             DisposeComponentOpenlogProc(cfupp);
  100.             res=(ComponentResult)lval;
  101.             break;
  102.         case ksyslogSelector:
  103.             cfupp=(ComponentFunctionUPP)NewComponentSyslogProc(ComponentSyslog);
  104.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  105.             DisposeComponentSyslogProc(cfupp);
  106.             res=(ComponentResult)lval;
  107.             break;
  108.         case kcloselogSelector:
  109.             cfupp=(ComponentFunctionUPP)NewComponentHandleProc(ComponentCloselog);
  110.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  111.             DisposeComponentHandleProc(cfupp);
  112.             res=(ComponentResult)lval;
  113.             break;
  114.         case ksetlogmaskSelector:
  115.             cfupp=(ComponentFunctionUPP)NewComponentSetlogmaskProc(ComponentSetlogmask);
  116.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  117.             DisposeComponentSetlogmaskProc(cfupp);
  118.             res=(ComponentResult)lval;
  119.             break;
  120.         case kSetFileSelector:
  121.             cfupp=(ComponentFunctionUPP)NewComponentSetFileProc(ComponentSetFile);
  122.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  123.             DisposeComponentSetFileProc(cfupp);
  124.             res=(ComponentResult)lval;
  125.             break;
  126.         case kGetErrorSelector:
  127.             cfupp=(ComponentFunctionUPP)NewComponentOSErrPtrProc(ComponentGetError);
  128.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  129.             DisposeComponentOSErrPtrProc(cfupp);
  130.             res=(ComponentResult)lval;
  131.             break;
  132.         
  133.         default:
  134.             res=badComponentSelector;
  135.             break;
  136.     }
  137.     
  138. #if defined(powerc) || defined(__powerc)
  139.     __rsrcterm();
  140. #endif
  141.     
  142.     return res;
  143. }
  144.  
  145. pascal ComponentResult ComponentOpen(Handle storage,ComponentInstance self){
  146.     ComponentStorageHdl storage,s);
  147.     
  148.     return res;
  149. }
  150.  
  151. // Add component specific routines here or in another file
  152.  
  153. /*
  154.     ComponentOpenlog
  155.     
  156.     Handles the opening of the syslog file.  Note that if we are opening an existing file, it's contents are
  157.     purged.
  158. */
  159. pascal ComponentResult ComponentOpenlog(Handle storage,const char* ident,long logopt,short facility){
  160.     ComponentResult res;
  161.     SignedByte s=HGetState(storage);
  162.     ComponentStorageHdl sto;
  163.     
  164.     HLock(storage);
  165.     sto=(ComponentStorageHdl)storage;
  166.     
  167.     // save the current stuff if necessary
  168.     if (!((*sto)->openCalled)){
  169.         // open called for the first time...
  170.         if ((*sto)->needSaved){
  171.             // the settings have changed, so we are not just resetting the syslog file
  172.             (*sto)->openCalled=true;
  173.             (*sto)->slogopts=(*sto)->logopts;
  174.             (*sto)->sfacility=(*sto)->facility;
  175.             (*sto)->smask=(*sto)->mask;
  176.         }
  177.     }
  178.     
  179.     if (Strlen((char*)ident)){
  180.         // save the current ident string
  181.         if (Strlen((char*)ident)>kMaxIdentLen){
  182.             Strncpy((*sto)->ident,(char*)ident,kMaxIdentLen);
  183.         } else {
  184.             Strcpy((*sto)->ident,(char*)ident);
  185.         }
  186.     } else {
  187.         (*sto)->ident[0]=0;
  188.     }
  189.     
  190.     // save the logopts
  191.     (*sto)->logopts=logopt;
  192.     
  193.     // save the facility
  194.     if ((facility!=0)&&((facility&~LOG_FACMASK)==0))
  195.         (*sto)->facility=facility;
  196.     
  197.     // purge the existing file if it exists
  198.     if ((*sto)->specvalid){
  199.         FInfo info;
  200.         
  201.         res=FSpGetFInfo(&((*sto)->spec),&info);
  202.         
  203.         if (res==noErr){
  204.             // the file exists, get rid of it
  205.             res=FSpDelete(&((*sto)->spec));
  206.             
  207.             if (res!=noErr){
  208.                 // file is busy or something, move it to the trash folder
  209.                 long dirid;
  210.                 short vref;
  211.                 FSSpec trash;
  212.                 
  213.                 // find the trash folder
  214.                 FindFolder(kOnSystemDisk,kTrashFolderType,kCreateFolder,&vref,&dirid);
  215.                 
  216.                 // make a spec for it
  217.                 FSMakeFSSpec(vref,dirid,(*sto)->spec.name,&trash);
  218.                 
  219.                 // allow the move to happen
  220.                 FSpCatMove(&((*sto)->spec),&trash);
  221.             }
  222.         }
  223.     }
  224.     
  225.     (*sto)->err=(OSErr)res;
  226.     
  227.     HSetState(storage,s);
  228.     
  229.     return res;
  230. }
  231.  
  232. pascal ComponentResult ComponentSyslog(Handle storage,short priority,const char* message){
  233.     ComponentResult res=noErr;
  234.     SignedByte s=HGetState(storage);
  235.     ComponentStorageHdl sto;
  236.     Str255 msg;
  237.     Str255 nstr;
  238.     long ct;
  239.     unsigned long time;
  240.     OSErr anErr=noErr;
  241.     char tempBuf[200];
  242.     
  243.     if (priority&~(LOG_PRIMASK|LOG_FACMASK)){
  244.         libsprintf(tempBuf,"syslog: unknown facility/priority: %x",priority);
  245.         ComponentSyslog(storage,LOG_ERR,tempBuf);
  246.         
  247.         priority&=LOG_PRIMASK|LOG_FACMASK;
  248.     }
  249.     
  250.     HLock(storage);
  251.     sto=(ComponentStorageHdl)storage;
  252.     
  253.     // if the priority clears the mask...  Basically if the bit in the mask is set for this priority,
  254.     // then we can continue (i.e. logging or notifying).
  255.     if ( (!LOG_MASK(LOG_PRI(priority))) & ((*sto)->mask) ){
  256.         anErr=noErr;
  257.         goto ExitSyslog;
  258.     }
  259.     
  260.     if ((priority&LOG_FACMASK)==0){
  261.         // use the default facility
  262.         priority|=(*sto)->facility;
  263.     }
  264.     
  265.     nstr[0]=0;
  266.     
  267.     switch (priority&LOG_PRIMASK){
  268.         case LOG_EMERG:
  269.             ConcatPString(nstr,"\p<Emergency> ");
  270.             break;
  271.         case LOG_ALERT:
  272.             ConcatPString(nstr,"\p<Alert> ");
  273.             break;
  274.         case LOG_CRIT:
  275.             ConcatPString(nstr,"\p<Critical> ");
  276.             break;
  277.         case LOG_ERR:
  278.             ConcatPString(nstr,"\p<Error> ");
  279.             break;
  280.         case LOG_WARNING:
  281.             ConcatPString(nstr,"\p<Warning> ");
  282.             break;
  283.         case LOG_INFO:
  284.             ConcatPString(nstr,"\p<Info> ");
  285.             break;
  286.         case LOG_DEBUG:
  287.             ConcatPString(nstr,"\p<Debug> ");
  288.             break;
  289.         case LOG_NOTICE:
  290.             ConcatPString(nstr,"\p<Notice> ");
  291.             break;
  292.         default:
  293.             {
  294.                 // priority not in range, encode the number as a priority
  295.                 Str255 tstr;
  296.                 NumToString(priority,tstr);
  297.                 
  298.                 ConcatPString(nstr,"\p<");
  299.                 ConcatPString(nstr,tstr);
  300.                 ConcatPString(nstr,"\p> ");
  301.             }
  302.             break;
  303.     }
  304.     
  305.     ReadDateTime(&time); // get time
  306.     
  307.     // build the date string
  308.     IUDatePString(time,shortDate,msg,(Handle)(*sto)->i0h);
  309.     
  310.     // add it to the nstr
  311.     ConcatPString(nstr,msg);
  312.     ConcatPString(nstr,"\p ");
  313.     
  314.     // build the time string
  315.     IUTimePString(time,true,msg,(Handle)(*sto)->i0h);
  316.     
  317.     // add it to the nstr
  318.     ConcatPString(nstr,msg);
  319.     ConcatPString(nstr,"\p ");
  320.     
  321.     // add the ident
  322.     ct=Strlen((*sto)->ident);
  323.     if (ct>0){
  324.         BlockMoveData((*sto)->ident,&(nstr[nstr[0]+1]),ct);
  325.         nstr[0]+=ct;
  326.         ConcatPString(nstr,"\p ");
  327.     } else {
  328.         // use syslog:
  329.         ConcatPString(nstr,"\psyslog");
  330.     }
  331.     
  332.     // add the ': '
  333.     ConcatPString(nstr,"\p: ");
  334.     
  335.     /*
  336.         In normal syslog implementations, a connection is opened with the syslog daemon
  337.         and the string is passed to the syslog daemon for logging (and the console if the flag is
  338.         set).  The connection is usually an AF_UNIX connection, or local system connection.
  339.         
  340.         In this component, we open a file, add the message, then close the file.  Close enough to
  341.         a local system connection for me ;-)
  342.         
  343.         Barring any crashes while the file is open, this will ensure that the file is updated and
  344.         closed so no messages are lost.
  345.         
  346.         This also means that when I write a syslog daemon that I can have the daemon open a file
  347.         and write this information into it just as easily.
  348.     */
  349.     
  350.     // add the message to the log file
  351.     if ((*sto)->specvalid){
  352.         // open the file
  353.         anErr=FSpOpenDF(&((*sto)->spec),fsRdWrPerm,&((*sto)->refnum));
  354.         
  355.         // move to the end of the file if it's open
  356.         if (anErr==noErr)
  357.             SetFPos((*sto)->refnum,fsFromLEOF,0L);
  358.         else {
  359.             (*sto)->refnum=0;
  360.             
  361.             // problem opening the file, try to create it...
  362.             anErr=FSpCreate(&((*sto)->spec),kSyslogCreator,'TEXT',smSystemScript);
  363.             
  364.             if (anErr==noErr){
  365.                 // if the file was just created, then we don't need to seek, just open
  366.                 anErr=FSpOpenDF(&((*sto)->spec),fsRdWrPerm,&((*sto)->refnum));
  367.                 if (anErr!=noErr)
  368.                     (*sto)->refnum=0;
  369.             } else {
  370.                 // DebugNotify("\pLog component: Error creating the file!");
  371.             }
  372.         }
  373.         
  374.         if ((anErr==noErr)&&((*sto)->refnum!=0)){
  375.             // OK to write to the file, add the nstr first
  376.             ct=(long)(nstr[0]);
  377.             FSWrite((*sto)->refnum,&ct,&(nstr[1]));
  378.             
  379.             // add the message to the file
  380.             ct=(long)Strlen((char*)message);
  381.             FSWrite((*sto)->refnum,&ct,message);
  382.             
  383.             // now add a newline char
  384.             msg[1]=0x0d;
  385.             ct=1;
  386.             FSWrite((*sto)->refnum,&ct,&(msg[1]));
  387.             
  388.             // done, flush & close file
  389.             FSClose((*sto)->refnum);
  390.             (*sto)->refnum=0;
  391.             FlushVol((StringPtr)0,(*sto)->spec.vRefNum);
  392.         }
  393.     } else {
  394.         anErr=2002; // fsspec is invalid
  395.     }
  396.     
  397. ExitSyslog:
  398.     (*sto)->err=anErr;
  399.     
  400.     HSetState(storage,s);
  401.     
  402.     return res;
  403. }
  404.  
  405. pascal ComponentResult ComponentCloselog(Handle storage){
  406.     ComponentResult res=noErr;
  407.     SignedByte s=HGetState(storage);
  408.     ComponentStorageHdl sto;
  409.     
  410.     HLock(storage);
  411.     sto=(ComponentStorageHdl)storage;
  412.     
  413.     // the current log should be closed and the old syslog reused.
  414.     
  415.     if ((*sto)->openCalled){
  416.         // open was called and the settings were changed
  417.         // restore the settings to the default values.
  418.         
  419.         (*sto)->openCalled=false;
  420.         (*sto)->facility=(*sto)->sfacility;
  421.         (*sto)->mask=(*sto)->smask;
  422.         (*sto)->logopts=(*sto)->slogopts;
  423.         (*sto)->needSaved=false;
  424.         (*sto)->ident[0]=0;
  425.         
  426.         if (((*sto)->vRefNum!=0)&&((*sto)->dirID!=0L)){
  427.             FSMakeFSSpec((*sto)->vRefNum,(*sto)->dirID,"\psyslog",&((*sto)->spec));
  428.             (*sto)->specvalid=true;
  429.         } else {
  430.             (*sto)->specvalid=false;
  431.         }
  432.     }
  433.     
  434.     HSetState(storage,s);
  435.     
  436.     return res;
  437. }
  438.  
  439. pascal ComponentResult ComponentSetlogmask(Handle storage,short maskpri){
  440.     ComponentResult res;
  441.     SignedByte s=HGetState(storage);
  442.     ComponentStorageHdl sto;
  443.     
  444.     HLock(storage);
  445.     sto=(ComponentStorageHdl)storage;
  446.     
  447.     res=(ComponentResult)(*sto)->mask;
  448.     
  449.     // save the new mask
  450.     if (maskpri!=0)
  451.         (*sto)->mask=maskpri;
  452.     (*sto)->needSaved=true;
  453.     
  454.     HSetState(storage,s);
  455.     
  456.     return res;
  457. }
  458.  
  459. pascal ComponentResult ComponentSetFile(Handle storage,FSSpecPtr spec){
  460.     ComponentResult res;
  461.     SignedByte s=HGetState(storage);
  462.     ComponentStorageHdl sto;
  463.     Boolean didClose=false;
  464.     
  465.     HLock(storage);
  466.     sto=(ComponentStorageHdl)storage;
  467.     
  468.     (*sto)->specvalid=false;
  469.     
  470.     // save the fsspec stuff
  471.     res=FSMakeFSSpec(spec->vRefNum,spec->parID,spec->name,&((*sto)->spec));
  472.     
  473.     if ((res==noErr)||(res==fnfErr)){
  474.         (*sto)->specvalid=true;
  475.         (*sto)->needSaved=true;
  476.     }
  477.     
  478.     HSetState(storage,s);
  479.     
  480.     return res;
  481. }
  482.  
  483. pascal ComponentResult ComponentGetError(Handle storage,OSErr* err){
  484.     ComponentResult res=noErr;
  485.     SignedByte s=HGetState(storage);
  486.     ComponentStorageHdl sto;
  487.     
  488.     HLock(storage);
  489.     sto=(ComponentSto